home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / Lattice C v5.02 d4.adf / examples / popcli.c < prev    next >
C/C++ Source or Header  |  1988-11-07  |  15KB  |  472 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\ Copyright (c) 1986 The Software Distillery.  All Rights Reserved */
  3. /* |. o.| || This program may not be distributed without the permission of   */
  4. /* | .  | || the authors.                                                    */
  5. /* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
  6. /* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
  7. /* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9. /*
  10.  * VERY loosely based on the input.device example by Rob Peck, 12/1/85
  11.  */
  12.  
  13. /* * * * * * * * * INCLUDE FILES * * * * * * * * * * * */
  14. #include <exec/types.h>
  15. #include <exec/nodes.h>
  16. #include <exec/lists.h>
  17. #include <exec/memory.h>
  18. #include <exec/interrupts.h>
  19. #include <exec/ports.h>
  20. #include <exec/libraries.h>
  21. #include <exec/io.h>
  22. #include <exec/tasks.h>
  23. #include <exec/execbase.h>
  24. #include <exec/devices.h>
  25. #include <devices/timer.h>
  26. #include <devices/input.h>
  27. #include <devices/inputevent.h>
  28. #include <intuition/intuition.h>
  29. #include <libraries/dos.h>
  30. #include <graphics/gfxmacros.h>
  31. #include <hardware/custom.h>
  32. #include <hardware/dmabits.h>
  33. #include <proto/dos.h>
  34. #include <proto/exec.h>
  35. #include <proto/intuition.h>
  36. #include <proto/graphics.h>
  37. #include <string.h>
  38.  
  39. /* * * * * * * * * * * CONSTANTS * * * * * * * * * * * * */
  40. #define PORTNAME     "POPCLI_III.port"
  41. #define TIMEINTERVAL 1L      /* in seconds */
  42. #define DEFTIME      300     /* two minute timeout */
  43. #define MAXCMD       200
  44. #define DEFKEY    0x45
  45. #define DEFCMD    "NEWCLI >NIL: <NIL:"
  46. #define KILLMSG "\x9B1mPOPCLI III\x9B0m Terminating\n"
  47. #define BANNER "\x9B0;33mPOPCLI III\x9B0m by John Toebes - Copyright \xA9 1987 The Software Distillery\n 235 Trillingham Ln, Cary NC 27511   BBS:(919)-471-6436\n"
  48. #define BANNER1 "Usage: \x9B1mPOPCLI\x9B0m [secs [command]]\nsecs is number of seconds before blanking screen\ncommand is to be executed when Left Amiga-Escape is pressed\n"
  49. /* * * * * * * * * * * GLOBAL VARIABLES * * * * * * * * * */
  50. typedef struct
  51.    {
  52.    struct Task          *buddy;
  53.    ULONG                 creatclisig;
  54.    ULONG                 unblanksig;
  55.    ULONG                 noevents;
  56.    short                 creatsignum;
  57.    short                 blanksignum;
  58.    short                 key;
  59.    struct Screen        *blankscreen;
  60.    } GLOBAL_DATA;
  61.  
  62. struct MsgPort *FindPort(), *CreatePort();
  63. void DeletePort();
  64.  
  65. struct OURMSG {
  66.  struct Message msgpart;
  67.  short key;
  68.  short interval;
  69.  char cmd[MAXCMD];
  70.  };
  71.  
  72. /* Declarations for CBACK */
  73. extern BPTR _Backstdout;         /* standard output when run in background */
  74. long _BackGroundIO = 1;          /* Flag to tell it we want to do I/O      */
  75. long _stack = 4000;              /* Amount of stack space our task needs   */
  76. char *_procname = "PopCLI III";  /* The name of the task to create         */
  77. long _priority = 20;             /* The priority to run us at              */
  78.  
  79. /************************************************************************/
  80. /* the handler subroutine - called through the handler stub             */
  81. /************************************************************************/
  82. struct InputEvent *myhandler(ev, gptr)
  83. struct InputEvent *ev;      /* and a pointer to a list of events */
  84. register GLOBAL_DATA *gptr;      /* Everything we need to know about */
  85.    {
  86.    register struct InputEvent *ep, *laste;
  87.  
  88.    /* run down the list of events to see if they pressed the magic button */
  89.    for (ep = ev, laste = NULL; ep != NULL; ep = ep->ie_NextEvent)
  90.       {
  91.       if ((ep->ie_Class == IECLASS_RAWKEY)    &&
  92.           (ep->ie_Code  == gptr->key)         &&
  93.           (ep->ie_Qualifier & IEQUALIFIER_LCOMMAND))
  94.          {
  95.          /* we can handle this event so take it off the chain */
  96.          if (laste == NULL)
  97.             ev = ep->ie_NextEvent;
  98.          else
  99.             laste->ie_NextEvent = ep->ie_NextEvent;
  100.          /* now tell him to create the new cli */
  101.          Signal(gptr->buddy, gptr->creatclisig);
  102.          }
  103.       else
  104.          laste = ep;
  105.  
  106.       if (ep->ie_Class != IECLASS_TIMER)
  107.          {
  108.          gptr->noevents = 0;
  109.          if (gptr->blankscreen != NULL)
  110.             Signal(gptr->buddy, gptr->unblanksig);
  111.          }
  112.       }
  113.  
  114.    /* pass on the pointer to the event */
  115.    return(ev);
  116.    }
  117.  
  118. /* * * * * * * * * * * EXTERNAL ROUTINES * * * * * * * * * */
  119. struct IntuitionBase *IntuitionBase;
  120. struct GfxBase       *GfxBase;
  121. struct DosLibrary    *DosBase;
  122.  
  123. extern struct Custom custom;
  124.  
  125. struct Custom *customptr = &custom;
  126. #define custom (*customptr)
  127.  
  128. struct NewScreen      NewScreen = 
  129.    { 0, 0, 320, 30, 1, 0, 1, NULL, CUSTOMSCREEN, NULL, NULL, NULL, NULL };
  130.  
  131. extern struct MsgPort  *CreatePort();
  132. struct IOStdReq *CreateIOReq(struct MsgPort *, int);
  133. void DeleteIOReq(struct IOStdReq *);
  134. extern void             HandlerInterface();
  135.  
  136. /************************************************************************/
  137. /* Queue a timer to go off in a given number of seconds                 */
  138. /************************************************************************/
  139. void QueueTimer(tr,seconds)
  140. struct timerequest *tr;
  141. ULONG seconds;
  142.    {
  143.    tr->tr_node.io_Command = TR_ADDREQUEST;   /* add a new timer request */
  144.    tr->tr_time.tv_secs =  seconds;            /* seconds */
  145.    tr->tr_time.tv_micro = 0;
  146.    SendIO( (struct IORequest *)tr );
  147.    }
  148.  
  149. /************************************************************************/
  150. /* the main program to do the popcli stuff                              */
  151. /************************************************************************/
  152. void _main(cmd)
  153. char *cmd;
  154.    {
  155.    struct MsgPort *port;
  156.    int stay = 0;
  157.    struct OURMSG *msg;
  158.  
  159.    char cmdstr[MAXCMD];
  160.    short key, timeout;
  161.    BPTR  nullfh;
  162.    ULONG sig, timersig;
  163.    struct timerequest *timerreq;
  164.    struct MsgPort     *timerport;
  165.    struct MsgPort     *inputDevPort;
  166.    struct IOStdReq    *inputRequestBlock;
  167.    struct Interrupt      handlerStuff;
  168.    GLOBAL_DATA global;
  169.  
  170.    global.creatsignum  = -1;
  171.    global.blanksignum  = -1;
  172.    timerreq            = NULL;
  173.    timerport           = NULL;
  174.    inputDevPort        = NULL;
  175.    inputRequestBlock   = NULL;
  176.  
  177.    /* now see if we are already installed */
  178.    if ((port = FindPort(PORTNAME)) == NULL)
  179.       {
  180.       stay = 1; /* remember to hang around when we are done */
  181.       /* not installed, we need to install our own port */
  182.       if ((port = CreatePort(PORTNAME,0)) == NULL)
  183.          goto abort;
  184.       }
  185.  
  186.    /* now send the parameter to the waiting program */
  187.    if ((msg = (struct OURMSG *)
  188.               AllocMem(sizeof(struct OURMSG), MEMF_CLEAR|MEMF_PUBLIC)) == NULL)
  189.       goto abort;
  190.  
  191.    /* fill in the message information */
  192.    msg->msgpart.mn_Length = sizeof(struct OURMSG);
  193.  
  194.    strcpy(cmdstr, DEFCMD);
  195.  
  196.    /* if we were run from CLI then output our banner and process parameters */
  197.    if (cmd && *cmd)
  198.       {
  199.       /* display our copyright */
  200.       if (stay && _Backstdout)
  201.          Write(_Backstdout, BANNER, sizeof(BANNER));
  202.  
  203.       /* skip over any leading spaces in the command line */
  204.       while(*cmd != ' ')
  205.          cmd++;
  206.       while(*cmd == ' ')
  207.          cmd++;
  208.  
  209.       /* see if they are trying to kill us. */
  210.       if (!stricmp(cmd, "QUIT\n"))
  211.          {
  212.          timeout = -1;
  213.          if (_Backstdout)
  214.             Write(_Backstdout, KILLMSG, sizeof(KILLMSG));
  215.          }
  216.       else if ((*cmd < ' ') && _Backstdout)
  217.          {
  218.          Write(_Backstdout, BANNER1, sizeof(BANNER1));
  219.          key = DEFKEY;
  220.          timeout = DEFTIME;
  221.          msg->cmd[0] = 0;  /* don't change the command string */
  222.          }
  223.       else
  224.          {
  225.          /* see if they gave us a number to control the interval of checking */
  226.          timeout = 0;
  227.          key = 0;
  228.  
  229.          while ((*cmd >= '0') && (*cmd <= '9'))
  230.             /* Multiply it by 10 without using a subroutine */
  231.             timeout = (timeout*10) + *cmd++ - '0';
  232.  
  233.          if (timeout <= 0)
  234.             timeout = DEFTIME;
  235.  
  236.          while (*cmd == ' ') cmd++;
  237.  
  238.          /* see if they gave us a number to control the interval of checking */
  239.          while ((*cmd >= '0') && (*cmd <= '9'))
  240.             /* Multiply it by 10 without using a subroutine */
  241.             key = (key*10) + *cmd++ - '0';
  242.  
  243.          if (key == 0)
  244.             key = DEFKEY;
  245.  
  246.          while (*cmd == ' ') cmd++;
  247.          strcpy(msg->cmd, cmd);
  248.          msg->cmd[strlen(cmd)-1] = 0;  /* wipe out the EOL character */
  249.          }
  250.       }
  251.    else
  252.       {
  253.       timeout = DEFTIME;
  254.       key = DEFKEY;
  255.       msg->cmd[0] = 0;
  256.       }
  257.  
  258.    msg->interval = timeout;
  259.    msg->key = key;
  260.  
  261.    PutMsg(port,(struct Message *)msg);
  262.  
  263.    if (!stay) goto abort;
  264.  
  265.    /* Lst the original window go away */
  266.    if (_Backstdout)
  267.       Close(_Backstdout);
  268.  
  269.    _Backstdout = 0;
  270.  
  271.    global.blankscreen = NULL;
  272.  
  273.    global.buddy = FindTask(0);
  274.    global.noevents = 0;
  275.  
  276.    /* set the input and output streams to 0 so execute doen't complain */
  277.    nullfh = Open("NIL:", MODE_NEWFILE);
  278.  
  279.    if (((inputDevPort = CreatePort(0,0)) == NULL)                          ||
  280.  
  281.       ((inputRequestBlock =
  282.           CreateIOReq(inputDevPort, sizeof(struct IOStdReq))) == NULL)     ||
  283.  
  284.       ((timerport = CreatePort(0,0)) == NULL)                              ||
  285.  
  286.       ((timerreq  = (struct timerequest *)
  287.           CreateIOReq(timerport, sizeof(struct timerequest))) == NULL)     ||
  288.  
  289.       ((global.creatsignum = AllocSignal(-1)) == -1)                       ||
  290.  
  291.       ((global.blanksignum = AllocSignal(-1)) == -1)                       ||
  292.  
  293.       ((GfxBase = (struct GfxBase *)
  294.                   OpenLibrary("graphics.library", 0)) == NULL)             ||
  295.  
  296.       ((IntuitionBase = (struct IntuitionBase *)
  297.                         OpenLibrary("intuition.library", 0)) == NULL)      ||
  298.       OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0)  ||
  299.  
  300.       OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0))
  301.  
  302.       goto abort;
  303.  
  304.    handlerStuff.is_Data = (APTR)&global;
  305.    handlerStuff.is_Code = HandlerInterface;
  306.    handlerStuff.is_Node.ln_Pri = 51;
  307.  
  308.    timersig            = (1 << timerport->mp_SigBit);
  309.    global.creatclisig  = 1 << global.creatsignum;
  310.    global.unblanksig   = 1 << global.blanksignum;
  311.  
  312.    inputRequestBlock->io_Command = IND_ADDHANDLER;
  313.    inputRequestBlock->io_Data    = (APTR)&handlerStuff;
  314.  
  315.    DoIO((struct IORequest *)inputRequestBlock);
  316.  
  317.    QueueTimer(timerreq, TIMEINTERVAL);
  318.  
  319.    for(;;)         /* FOREVER */
  320.       {
  321.       sig = Wait( global.creatclisig | global.unblanksig | timersig );
  322.  
  323.       /* see if they asked us to change the interval */
  324.       if ((msg = (struct OURMSG *)GetMsg(port)) != NULL)
  325.          {
  326.          if (msg->cmd[0]) strcpy(cmdstr, msg->cmd);
  327.          global.key = msg->key;
  328.          timeout    = msg->interval;
  329.          FreeMem((char *)msg, msg->msgpart.mn_Length);
  330.  
  331.          if (global.key == 0) goto abort;
  332.          }
  333.  
  334.       if ((sig & global.unblanksig) && global.blankscreen)
  335.          {
  336.          CloseScreen(global.blankscreen);
  337.      ON_DISPLAY
  338.          global.blankscreen = NULL;
  339.          }
  340.  
  341.       if (sig & global.creatclisig)
  342.          {
  343.          WBenchToFront();
  344.          (void)Execute(cmdstr,nullfh,nullfh);
  345.          }
  346.  
  347.       if (sig & timersig)
  348.          {
  349.          /* get rid of the message */
  350.          (void)GetMsg(timerport);
  351.          QueueTimer(timerreq, TIMEINTERVAL);
  352.  
  353.          if ((global.noevents++ >= timeout) && (global.blankscreen == NULL))
  354.             {
  355.             if ( (global.blankscreen = OpenScreen(&NewScreen)) != NULL)
  356.                {
  357.                SetRGB4(&(global.blankscreen->ViewPort), 0, 0, 0, 0);
  358.                OFF_DISPLAY
  359.                }
  360.             }
  361.          }
  362.  
  363.       /* Force our screen to front on a regular basis to handle something   */
  364.       /* that might put their stuff in front of us while we are supposed to */
  365.       /* Be blanking the screen.                                            */
  366.       if (global.blankscreen)
  367.          {
  368. #if 0
  369.          /* Unfortunately doing this causes the screen to flash momentarily */
  370.          /* Which makes it look ugly.  Perhaps someone can come up with a   */
  371.          /* Better way to force us upfront..                                */
  372.          ScreenToFront(global.blankscreen);
  373. #endif
  374.          OFF_DISPLAY
  375.          }
  376.       }
  377.  
  378. abort:
  379.    if (timerreq != NULL)
  380.       {
  381.       if (timerreq->tr_node.io_Device != NULL)
  382.          CloseDevice((struct IORequest *)timerreq);
  383.       DeleteIOReq((struct IOStdReq *)timerreq);
  384.       }
  385.    if (inputRequestBlock != NULL)
  386.       {
  387.       if (inputRequestBlock->io_Device != NULL)
  388.          {
  389.          inputRequestBlock->io_Command = IND_REMHANDLER;
  390.          inputRequestBlock->io_Data = (APTR)&handlerStuff;
  391.          DoIO((struct IORequest *)inputRequestBlock);
  392.  
  393.          CloseDevice((struct IORequest *)inputRequestBlock);
  394.          }
  395.       DeleteIOReq(inputRequestBlock);
  396.       }
  397.    if (timerport != NULL)          DeletePort(timerport);
  398.    if (global.creatsignum != -1)   FreeSignal(global.creatsignum);
  399.    if (global.blanksignum != -1)   FreeSignal(global.blanksignum);
  400.    if (global.blankscreen != NULL) CloseScreen(global.blankscreen);
  401.    if (IntuitionBase != NULL)      CloseLibrary((struct Library *)IntuitionBase);
  402.    if (GfxBase != NULL)            CloseLibrary((struct Library *)GfxBase);
  403.    if (inputDevPort != NULL)       DeletePort(inputDevPort);
  404.    if (_Backstdout)                Close(_Backstdout);
  405.    if (stay && (port != NULL))     DeletePort(port);
  406.    if (nullfh)                     Close(nullfh);
  407.    }
  408.  
  409. void MemCleanup(){}
  410.  
  411. struct MsgPort *CreatePort(name, pri)
  412. char *name;
  413. int pri;
  414. {
  415.    UBYTE sigbit;
  416.    register struct MsgPort *port;
  417.  
  418.    if ((sigbit = AllocSignal(-1)) == -1)
  419.       return((struct MsgPort *)0);
  420.  
  421.    if ((port = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),
  422.                         MEMF_CLEAR|MEMF_PUBLIC)) == 0)
  423.       {
  424.       FreeSignal(sigbit);
  425.       return((struct MsgPort *) (0));
  426.       }
  427.    port->mp_Node.ln_Name = name;
  428.    port->mp_Node.ln_Pri = pri;
  429.    port->mp_Node.ln_Type = NT_MSGPORT;
  430.    port->mp_Flags = PA_SIGNAL;
  431.    port->mp_SigBit = sigbit;
  432.    port->mp_SigTask = (struct Task *)FindTask(0);
  433.    AddPort(port);
  434.    return(port);
  435. }
  436.  
  437. void DeletePort(port)
  438. struct MsgPort *port;
  439. {
  440. RemPort(port);
  441. FreeSignal(port->mp_SigBit);
  442. FreeMem((char *)port,sizeof(struct MsgPort));
  443. }
  444.  
  445. struct IOStdReq *
  446. CreateIOReq(port, size)
  447. struct MsgPort *port;
  448. int size;
  449. {
  450.    struct IOStdReq *ioReq;
  451.  
  452.    if ((ioReq = (struct IOStdReq *)
  453.                 AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
  454.       {
  455.       ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  456.       ioReq->io_Message.mn_Node.ln_Pri  = 0;
  457.       ioReq->io_Message.mn_Length       = size;
  458.       ioReq->io_Message.mn_ReplyPort    = port;
  459.       }
  460.    return(ioReq);
  461. }
  462.  
  463. void DeleteIOReq(ioReq)
  464. struct IOStdReq *ioReq;
  465. {
  466. ioReq->io_Message.mn_Node.ln_Type = 0xff;
  467. ioReq->io_Device = (struct Device *) -1;
  468. ioReq->io_Unit = (struct Unit *) -1;
  469.  
  470. FreeMem( (char *)ioReq, ioReq->io_Message.mn_Length);
  471. }
  472.